﻿using System.Reflection;
using CommunityToolkit.Mvvm.DependencyInjection;
using FanaticRock.Core.DI;
using FanaticRock.Core.Extensions;
using FanaticRock.Core.Helpers;
using FanaticRock.Core.Interfaces;
using Microsoft.Extensions.DependencyInjection;

namespace FanaticRock
{
    public partial class App : ILogger
    {
        public void Init()
        {
            InitIoc();
        }

        private static Type[] RuntimeTypes()
        {
            return new[]{
                typeof(App),
                typeof(AudioManage.Properties.AssemblyInfo),
                typeof(TestDataSource.Properties.AssemblyInfo),
                typeof(BilibiliShell.Properties.AssemblyInfo),
                typeof(Database.Properties.AssemblyInfo),
                typeof(DownloadManage.Properties.AssemblyInfo),
            };
        }

        private void InitIoc()
        {
            var serviceCollection = new ServiceCollection();

            var pairList = ServiceProviderBuilder.Resolve(RuntimeTypes().Select(t => t.Assembly));

            foreach (var pair in pairList)
            {
                AddService(serviceCollection, pair);

                this.Info(pair);
            }

            var serviceProvider = serviceCollection.BuildServiceProvider();

            Ioc.Default.ConfigureServices(serviceProvider);


        }

   

        private static void AddService(ServiceCollection serviceCollection, ClassDIInfo pair)
        {
            if (pair.LiftTimeType == InjectMeAttribute.LifeTimeEnum.Singleton)
            {
                AddSingleton(serviceCollection, pair);
            }
            else
            {
                AddTransient(serviceCollection, pair);
            }
        }

        private static void AddTransient(ServiceCollection serviceCollection, ClassDIInfo pair)
        {
            if (pair is ClassInterfaceDIPair pairInfo)
            {
                serviceCollection.AddTransient(pairInfo.InterfaceType, pair.ClassType);
            }
            else if (pair is ClassDIInfo classInfo)
            {
                serviceCollection.AddTransient(pair.ClassType);
            }
        }

        private static void AddSingleton(ServiceCollection serviceCollection, ClassDIInfo pair)
        {
            if (pair is ClassInterfaceDIPair pairInfo)
            {
                serviceCollection.AddSingleton(pairInfo.InterfaceType, pair.ClassType);
            }
            else if (pair is ClassDIInfo classInfo)
            {
                serviceCollection.AddSingleton(pair.ClassType);
            }
        }
    }
}
